package br.com.pucrs.tcc.bd;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

import br.com.pucrs.tcc.ed.Aluno;
import br.com.pucrs.tcc.ed.GrupoTrabalho;
import br.com.pucrs.tcc.enumerator.SituacaoGrupoTrabalhoEnum;
import br.com.pucrs.tcc.vo.GrupoFiltro;

public class GrupoTrabalhoBD {

	private Session mSession;

	public GrupoTrabalhoBD(Session session) {
		mSession = session;
	}

	public void insert(GrupoTrabalho grupo) {
		mSession.save(grupo);
		mSession.flush();
	}

	public void update(GrupoTrabalho grupo) {
		mSession.update(grupo);
	}

	public void delete(GrupoTrabalho grupo) {
		mSession.delete(grupo);
		mSession.flush();
	}

	public GrupoTrabalho retrieve(GrupoTrabalho grupo) {
		// System.out.println("BD ahsduadhasihdai");
		// GrupoTrabalho grupoRetorno = null;
		//
		// grupoRetorno = (GrupoTrabalho) mSession.load(GrupoTrabalho.class,
		// grupo.getId());
		//
		// return grupoRetorno;

		GrupoTrabalho retorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append("      WHERE gt.id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		query.setInteger(0, grupo.getId());

		retorno = (GrupoTrabalho) query.uniqueResult();

		return retorno;
	}

	public ArrayList<GrupoTrabalho> list(GrupoTrabalho grupo) {
		ArrayList<GrupoTrabalho> listaRetorno = null;

		Criteria criteria = mSession.createCriteria(GrupoTrabalho.class);
		// criteria.add(Restrictions.eq("matricula", professor.getMatricula()));

		listaRetorno = (ArrayList<GrupoTrabalho>) criteria.list();

		if (listaRetorno != null) {
			System.out.println(listaRetorno.size());
		} else {
			System.out.println("AREA.NULL");
		}

		return listaRetorno;
	}

	public ArrayList<GrupoTrabalho> list(String matriculaAluno) {
		return list(matriculaAluno, false);
	}

	public ArrayList<GrupoTrabalho> list(String matriculaAluno, boolean bCancelados) {
		ArrayList<GrupoTrabalho> listaRetorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append(" INNER JOIN alunos_grupos_trabalho agt ");
		sql.append("         ON (gt.id = agt.grupos_trabalho_id) ");
		sql.append("      WHERE agt.alunos_matricula = ? ");
		if (!bCancelados) {
			sql.append("        AND gt.situacao <> 11 ");
		}
		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		query.setString(0, matriculaAluno);

		listaRetorno = (ArrayList<GrupoTrabalho>) query.list();

		return listaRetorno;
	}

	public GrupoTrabalho listUnique(String matriculaAluno) {
		GrupoTrabalho retorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append(" INNER JOIN alunos_grupos_trabalho agt ");
		sql.append("         ON (gt.id = agt.grupos_trabalho_id) ");
		sql.append("      WHERE agt.alunos_matricula = ? ");
		sql.append("        AND gt.situacao in (?, ?, ?, ?) ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		query.setString(0, matriculaAluno);
		query.setInteger(1, SituacaoGrupoTrabalhoEnum.FORMADO.getCodigo());
		query.setInteger(2, SituacaoGrupoTrabalhoEnum.AGUARDANDO_PROFESSOR.getCodigo());
		query.setInteger(3, SituacaoGrupoTrabalhoEnum.AGUARDANDO_PROFESSOR_CONVITE.getCodigo());
		query.setInteger(4, SituacaoGrupoTrabalhoEnum.AGUARDANDO_CONVITE.getCodigo());

		retorno = (GrupoTrabalho) query.uniqueResult();

		return retorno;
	}

	public Integer countComOrientador() {
		Integer retorno = 0;

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT gt.*");
		sql.append("   FROM grupos_trabalho gt");
		sql.append("  WHERE gt.professores_matricula is not null");
		sql.append("    AND gt.situacao in (1,2,3,4,5,6) ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		retorno = query.list().size();

		return retorno;
	}

	public Integer countSemOrientador() {
		Integer retorno = 0;

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT gt.*");
		sql.append("   FROM grupos_trabalho gt");
		sql.append("  WHERE gt.professores_matricula is null");
		sql.append("    AND gt.situacao in (1,2,3,4,5,6)");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		retorno = query.list().size();

		return retorno;
	}

	public ArrayList<GrupoTrabalho> listAlocacao() {
		ArrayList<GrupoTrabalho> retorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT gt.* ");
		sql.append("   FROM grupos_trabalho gt ");
		sql.append("  WHERE gt.professores_matricula is null ");
		sql.append("    AND gt.situacao IN (2,3,4,5) ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);

		retorno = (ArrayList<GrupoTrabalho>) query.list();

		return retorno;
	}

	public ArrayList<GrupoTrabalho> listAlocados() {
		ArrayList<GrupoTrabalho> retorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT gt.* ");
		sql.append("   FROM grupos_trabalho gt ");
		sql.append("  WHERE gt.situacao in (6, 7)");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);

		retorno = (ArrayList<GrupoTrabalho>) query.list();

		return retorno;
	}

	public Integer countAlunosGrupo(Integer id) {
		Integer retorno = 0;

		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT count(*) ");
		sql.append("   FROM alunos_grupos_trabalho agt ");
		sql.append("  WHERE agt.grupos_trabalho_id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.setInteger(0, id);

		BigInteger count = (BigInteger) query.uniqueResult();

		retorno = count.intValue();

		return retorno;
	}

	public Integer countFormandosGrupo(Integer id) {
		Integer retorno = 0;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT count(*) ");
		sql.append("       FROM alunos_grupos_trabalho agt ");
		sql.append(" INNER JOIN alunos a ");
		sql.append("         ON (agt.alunos_matricula = a.matricula) ");
		sql.append("      WHERE agt.grupos_trabalho_id = ? ");
		sql.append("        AND a.formando = true ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.setInteger(0, id);

		BigInteger count = (BigInteger) query.uniqueResult();

		retorno = count.intValue();

		return retorno;
	}

	public Double coeficienteRendimentoGrupo(Integer id) {
		Double retorno = 0.0;

		StringBuilder sql = new StringBuilder();
		sql.append("     SELECT MAX(coeficiente_rendimento) AS coeficiente_rendimento ");
		sql.append("            , a.matricula ");
		sql.append("            , a.formando ");
		sql.append("            , a.cursos_id ");
		sql.append("            , u.* ");
		sql.append("       FROM alunos_grupos_trabalho agt ");
		sql.append(" INNER JOIN alunos a ");
		sql.append("         ON (agt.alunos_matricula = a.matricula) ");
		sql.append(" INNER JOIN usuarios u ");
		sql.append("         ON (a.matricula = u.matricula) ");
		sql.append("      WHERE agt.grupos_trabalho_id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(Aluno.class);

		query.setInteger(0, id);

		Aluno aluno = (Aluno) query.uniqueResult();

		if (aluno != null) {
			System.out.println("coeficiente -> " + aluno.getCoeficienteRendimento());
			retorno = aluno.getCoeficienteRendimento();
		}

		return retorno;
	}

	public boolean alteraOrientador(GrupoTrabalho grupo) {
		boolean retorno = false;

		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE grupos_trabalho ");
		sql.append("   SET professores_matricula = ? ");
		sql.append("       , situacao = ? ");
		sql.append(" WHERE id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		if (grupo.getProfessor() != null) {
			query.setString(0, grupo.getProfessor().getMatricula());
		} else {
			query.setString(0, null);
		}
		query.setInteger(1, grupo.getSituacao());
		query.setInteger(2, grupo.getId());

		int result = query.executeUpdate();

		retorno = result == 1;

		return retorno;
	}

	public boolean retiraOrientador(GrupoTrabalho grupo) {
		boolean retorno = false;

		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE grupos_trabalho ");
		sql.append("   SET professores_matricula = NULL ");
		sql.append("       , situacao = ? ");
		sql.append(" WHERE id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.setInteger(0, grupo.getSituacao());
		query.setInteger(1, grupo.getId());

		int result = query.executeUpdate();

		retorno = result == 1;

		return retorno;
	}

	public boolean alteraSituacao(GrupoTrabalho grupo) {
		boolean retorno = false;

		StringBuilder sql = new StringBuilder();
		sql.append("UPDATE grupos_trabalho ");
		sql.append("   SET situacao = ? ");
		sql.append(" WHERE id = ? ");

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.setInteger(0, grupo.getSituacao());
		query.setInteger(1, grupo.getId());

		int result = query.executeUpdate();

		retorno = result == 1;

		return retorno;
	}

	public ArrayList<GrupoTrabalho> lista(GrupoFiltro grupoFiltro) {
		ArrayList<GrupoTrabalho> listaRetorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT DISTINCT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append(" INNER JOIN alunos_grupos_trabalho agt ");
		sql.append("         ON (gt.id = agt.grupos_trabalho_id) ");
		sql.append("      WHERE gt.situacao <> 11 ");
		

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		

		listaRetorno = (ArrayList<GrupoTrabalho>) query.list();

		return listaRetorno;
	}

	public ArrayList<GrupoTrabalho> listaPorProfessor(String matricula) {
		ArrayList<GrupoTrabalho> listaRetorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT DISTINCT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append("      WHERE gt.situacao <> 11 ");
		sql.append("        AND gt.professores_matricula = ? ");
		

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		query.setString(0, matricula);


		listaRetorno = (ArrayList<GrupoTrabalho>) query.list();

		return listaRetorno;
	}
	
	public ArrayList<GrupoTrabalho> listaTodosPorProfessor(String matricula) {
		ArrayList<GrupoTrabalho> listaRetorno = null;

		StringBuilder sql = new StringBuilder();

		sql.append("     SELECT DISTINCT gt.* ");
		sql.append("       FROM grupos_trabalho gt ");
		sql.append("      WHERE gt.professores_matricula = ? ");
		

		SQLQuery query = mSession.createSQLQuery(sql.toString());
		query.addEntity(GrupoTrabalho.class);
		query.setString(0, matricula);


		listaRetorno = (ArrayList<GrupoTrabalho>) query.list();

		return listaRetorno;
	}
	
	
}
